﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Quartz;
using Quartz.Impl;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using XfTechOAWeb.Dtos;
using XfTechOAWeb.Models;
using XfTechOAWeb.Service.Tasks;
using static Microsoft.EntityFrameworkCore.DbLoggerCategory;
using Dapper;
using System.Data;
using Microsoft.Data.SqlClient;
using System.Text;

namespace XfTechOAWeb.ApiServer.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    [AllowAnonymous] //允许匿名访问
    public class ValuesController : ControllerBase
    {

        [HttpGet("TestQuartZ")]
        public async Task<IActionResult> TestQuartZ()
        {
            //1. 创建一个调度器
            var scheduler = await new StdSchedulerFactory().GetScheduler();
            await scheduler.Start(); //启动
            //2. 创建一个工作任务
            var job = JobBuilder.Create<FirstJob>().Build();

            //3. 创建一个触发器（简单的、CRON触发器）
            //var trigger = TriggerBuilder.Create().WithSimpleSchedule(x =>{
            //    x.WithRepeatCount(3)       //循环次数
            //     .WithIntervalInSeconds(1);//间隔时间
            //}).Build();

            var trigger = TriggerBuilder.Create()
                                        .WithCronSchedule("* * * * * ? *")
                                        .Build();

            //将三个对象，连接在一起
            await scheduler.ScheduleJob(job, trigger);

            return Ok();
        }

        [HttpGet("TestReflection")]
        public IActionResult TestReflection(string typeName)
        {
            //查找程序集中的所有类型名字，与typeName进行匹配，
            Type t = Assembly.Load("XfTechOAWeb.Service").GetTypes()
                             .Where(x => x.Name == typeName).FirstOrDefault();
            if (t == null)
            {
                return BadRequest();
            }

            //var list = t.GetProperties(); //获取所有的属性信息
            //foreach (var item in list)
            //{
            //    Console.WriteLine("属性名：", item.Name);
            //}
            //todo: 调查一下怎么获得类里面的构造函数名称和 私有字段

            var list = t.GetMethods(); //获取所有的方法信息
            foreach (var item in list)
            {
                Console.WriteLine("方法名：", item.Name);
            }

            List<string> names = list.Select(x => x.Name).ToList(); //用Linq把所有的属性名转换成一个集合

            return Ok(names);
        }


        //用反射实现 ORM的简单例子
        //输入一个类型的数据，能够自动转换成SQL（以下这个例子，做添加操作）
        [HttpPost("TestORM")]
        public IActionResult TestORM(Role role)
        {
            //1. 获取输入参数的类型Type
            Type t = role.GetType();

            //2. 获取t里面的所有属性名称
            var props = t.GetProperties();

            //3. 拼接SQL语句
            string strSql = $"INSERT INTO {t.Name}s VALUES(";

            foreach (var p in props)
            {
                string strValue = p.GetValue(role).ToString();
                strSql += strValue + ",";
            }

            strSql = strSql.TrimEnd(',');
            strSql += ")";

            return Ok(strSql);
        }

        //todo:有待研究
        [HttpPost("TestIOC")]
        public IActionResult TestIOC(string typeName)
        {
            //输入类型名称

            //输出一个对象 （用反射去动态创建对象

            return Ok();
        }


        //用Dapper写一个接口方法，返回用户表的列表数据，（不带分页）

        //生成流水号的例子
        [NonAction]
        public string GetNumber()
        {
            using IDbConnection conn = new SqlConnection("");

            // 从数据库中获取当前编号
            string currentNumberSql = "SELECT current_number FROM number_control";
            int currentNumber = conn.ExecuteScalar<int>(currentNumberSql);


            // 生成日期字符串
            string dateFormatSql = "SELECT date_format FROM number_control";
            string dateFormat = conn.ExecuteScalar<string>(dateFormatSql);

            DateTime currentDate = DateTime.Now; // 获取当前日期
            string dateString = currentDate.ToString(dateFormat);
            
            // 生成编号字符串
            string integerDigitsSql = "SELECT integer_digits FROM number_control";
            string integerDigits = conn.ExecuteScalar<string>(integerDigitsSql);

            string numberString = currentNumber.ToString("D"+integerDigits);
            
            // 生成单号
            string orderPrefixSql = "SELECT order_prefix FROM number_control";
            string orderPrefix = conn.ExecuteScalar<string>(orderPrefixSql); ;

            string orderNumber = orderPrefix + dateString + numberString;
            
            // 更新当前编号
            currentNumber = currentNumber + 1;
            
            string sql = $"UPDATE number_control SET current_number = {currentNumber}";
            
            return orderNumber;
        }

    }
}

